package com.itcam.phaselist.set_;

import java.util.HashSet;

public class HashSetSource {
    public static void main(String[] args) {

        HashSet hashSet = new HashSet();
        hashSet.add("java是世界上最好的语言.py");
        hashSet.add("python");
        hashSet.add("C语言");
        hashSet.add("Golang");
        System.out.println("hashSet = " + hashSet);

        /**
         * HashSet源码解读
         * 1.执行HashSet()
         *  public HashSet() {
         *         map = new HashMap<>();
         *     }
         * 2.执行add()
         *  public boolean add(E e) {
         *         return map.put(e, PRESENT)==null; // PRESENT是一个对象，起到占位作用
         *         // private static final Object PRESENT = new Object();
         *     }
         * 3.执行put(),该方法会执行hash(key)方法得到对应的hash值
         *  public V put(K key, V value) {
         *         return putVal(hash(key), key, value, false, true);
         *     }
         *  static final int hash(Object key) {
         *         int h;
         *         return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
         *         // 这里hash值不是hashCode，因为做了处理
         *     }
         * 4.执行putVal
         *  final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
         *                    boolean evict) {
         *         Node<K,V>[] tab; Node<K,V> p; int n, i; // 定义了辅助变量
         *         if ((tab = table) == null || (n = tab.length) == 0)
         *             // table就是HashMap的一个数组，类型是Node[]
         *             // if语句表示如果当前table是null，或者大小=0就是第一次扩容到16个空间
         *             // 位左移相当于×2(同理位右移相当于÷2)后面的数字是多少就有多少个2 则1<<4 ==> 1×2×2×2×2=16
         *             n = (tab = resize()).length;
         *         if ((p = tab[i = (n - 1) & hash]) == null)
         *             // 上述代码相当于p = tab[i = tab[i = (n - 1) & hash] 和 p == null
         *             // (1)根据key，得到hash去计算key应该存放到table表的哪个索引位置并把这个位置赋值给p
         *             // (2)判断p是否为null
         *             // (2.1)如果p为空，表示还没有存放过元素，就创建一个Node(key="java是世界上最好的语言.py",value=PRESENT)
         *             // (2.2)把Node(key="java是世界上最好的语言.py",value=PRESENT)放在tab[i] = newNode(hash, key, value, null);
         *             tab[i] = newNode(hash, key, value, null);
         *         else {
         *             Node<K,V> e; K k;
         *             if (p.hash == hash &&
         *                 ((k = p.key) == key || (key != null && key.equals(k))))
         *                 e = p;
         *             else if (p instanceof TreeNode)
         *                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
         *             else {
         *                 for (int binCount = 0; ; ++binCount) {
         *                     if ((e = p.next) == null) {
         *                         p.next = newNode(hash, key, value, null);
         *                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
         *                             treeifyBin(tab, hash);
         *                         break;
         *                     }
         *                     if (e.hash == hash &&
         *                         ((k = e.key) == key || (key != null && key.equals(k))))
         *                         break;
         *                     p = e;
         *                 }
         *             }
         *             if (e != null) { // existing mapping for key
         *                 V oldValue = e.value;
         *                 if (!onlyIfAbsent || oldValue == null)
         *                     e.value = value;
         *                 afterNodeAccess(e);
         *                 return oldValue;
         *             }
         *         }
         *         ++modCount;
         *         if (++size > threshold)
         *             resize();
         *         afterNodeInsertion(evict); // 空方法，为了让HashMap的子类实现
         *         return null;
         *     }
         */
    }
}
